package com.nineclock.document.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.document.dto.DocFileDto;
import com.nineclock.document.dto.DocFolderDto;
import com.nineclock.document.dto.DocumentDto;
import com.nineclock.document.enums.DocumentPermissionEnum;
import com.nineclock.document.mapper.DocCollaborationsMapper;
import com.nineclock.document.mapper.DocFileHistoryMapper;
import com.nineclock.document.mapper.DocFileMapper;
import com.nineclock.document.mapper.DocFolderMapper;
import com.nineclock.document.pojo.DocCollaborations;
import com.nineclock.document.pojo.DocFile;
import com.nineclock.document.pojo.DocFileHistory;
import com.nineclock.document.pojo.DocFolder;
import com.nineclock.document.service.AppDocumentService;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.feign.SysUserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 * @Version 1.0
 */
@Service
public class AppDocumentServiceImpl implements AppDocumentService {



    @Override
    public DocumentDto queryFolderAndFile(Long parentFolderId) {
        DocumentDto documentDto = new DocumentDto();

        //查询文件夹列表
        List<DocFolderDto> docFolderDtoList = this.queryFolderList(parentFolderId);
        //文件文件列表
        List<DocFileDto> docFileDtoList = this.queryFileList(parentFolderId);

        //组合数据
        documentDto.setFolders(docFolderDtoList);
        documentDto.setFiles(docFileDtoList);

        return documentDto;
    }

    @Override
    public void insertFolder(DocFolderDto docFolderDto) {
        if(docFolderDto == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //转换dockFolder对象
        DocFolder docFolder = BeanHelper.copyProperties(docFolderDto, DocFolder.class);
        //设置其他的参数
        docFolder.setCompanyId(CurrentUserHolder.get().getCompanyId());
        docFolder.setOrderNum(0);
        docFolder.setCreateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFolder.setCreateTime(new Date());
        docFolder.setStatus((short)1);

        //保存到数据库
        folderMapper.insert(docFolder);

    }

    @Autowired
    DocFileHistoryMapper docFileHistoryMapper;

    @Override
    public void insertFile(DocFileDto docFileDto) {
        if(docFileDto == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        DocFile docFile = BeanHelper.copyProperties(docFileDto, DocFile.class);
        docFile.setCreateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFile.setCreateTime(new Date());
        docFile.setType((short)1);
        docFile.setPermission(DocumentPermissionEnum.PRIVATE_READ_WRITE.getPermission());
        docFile.setCompanyId(CurrentUserHolder.get().getCompanyId());
        docFile.setStatus((short)1);
        //保存文档信息
        docFileMapper.insert(docFile);

        //保存文档历史信息
        DocFileHistory docFileHistory = new DocFileHistory();
        docFileHistory.setFileId(docFile.getId());
        docFileHistory.setFileName(docFile.getName());
        docFileHistory.setOperateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFileHistory.setOperateTime(new Date());
        docFileHistory.setIsCreate((short)1);
        docFileHistory.setContent(docFile.getContent());

        docFileHistoryMapper.insert(docFileHistory);
    }

    @Override
    public DocFileDto getFileByFileId(Long fileId) {
        DocFile docFile = docFileMapper.selectById(fileId);
        if(docFile == null){
            throw new NcException(ResponseEnum.FILE_NOT_FOUND);
        }
        return BeanHelper.copyProperties(docFile,DocFileDto.class);
    }

    @Autowired
    DocFileMapper docFileMapper;

    @Autowired
    DocCollaborationsMapper collaborationsMapper;

    @Autowired
    SysUserFeign userFeign;

    private List<DocFileDto> queryFileList(Long parentFolderId) {
        Long companyId = CurrentUserHolder.get().getCompanyId();
        Long companyUserId = CurrentUserHolder.get().getCompanyUserId();
        //1. 查询可以公共读/公共读写的文件
        LambdaQueryWrapper<DocFile> docFileQw1 = new LambdaQueryWrapper<>();
        docFileQw1.eq(DocFile::getCompanyId, companyId);
        docFileQw1.eq(DocFile::getFolderId, parentFolderId);
        docFileQw1.eq(DocFile::getStatus, 1);
        docFileQw1.in(DocFile::getPermission, DocumentPermissionEnum.ALL_READ.getPermission(), DocumentPermissionEnum.ALL_READ_WRITE.getPermission());


        List<DocFile> docFileList1 = docFileMapper.selectList(docFileQw1);

        //2. 查询私有的文件(自己创建的文件)
        LambdaQueryWrapper<DocFile> docFileQw2 = new LambdaQueryWrapper<>();
        docFileQw2.eq(DocFile::getCompanyId, companyId);
        docFileQw2.eq(DocFile::getFolderId, parentFolderId);
        docFileQw2.eq(DocFile::getStatus, 1);
        docFileQw2.eq(DocFile::getPermission, DocumentPermissionEnum.PRIVATE_READ_WRITE.getPermission());
        docFileQw2.eq(DocFile::getCreateUserId, companyUserId ); // 本人id

        List<DocFile> docFileList2 = docFileMapper.selectList(docFileQw2);

        //3. 查询自己为协作者关联的文件
        List<DocFile> docFileList3 = null;
        //查询自己为协作者 关联的文件的id
        LambdaQueryWrapper<DocCollaborations> docCollaborationsQw = new LambdaQueryWrapper<>();
        docCollaborationsQw.eq(DocCollaborations::getCollaborationId, companyUserId);
        //协作者 集合数据
        List<DocCollaborations> collaborationsList = collaborationsMapper.selectList(docCollaborationsQw);
        //如果协作者 列表不为null ， 则取出 文件id
        if(CollectionUtil.isNotEmpty(collaborationsList)){
            List<Long> fileIds = collaborationsList.stream().map(docCollaborations -> {
                return docCollaborations.getFileId();
            }).collect(Collectors.toList());

            LambdaQueryWrapper<DocFile> docFileQw3 = new LambdaQueryWrapper<>();

            docFileQw3.eq(DocFile::getCompanyId, companyId);
            docFileQw3.eq(DocFile::getFolderId, parentFolderId);
            docFileQw3.eq(DocFile::getStatus, 1);
            docFileQw3.in(DocFile::getId, fileIds);

            docFileList3 =  docFileMapper.selectList(docFileQw3);

        }


        //组装文件集合
        List<DocFile> docFileList = new ArrayList<>();
        docFileList.addAll(docFileList1);
        docFileList.addAll(docFileList2);
        docFileList.addAll(docFileList3);
        
        //去重
        docFileList  = CollectionUtil.distinct(docFileList);


        // 转换数据集合
        List<DocFileDto> docFileDtoList = BeanHelper.copyWithCollection(docFileList, DocFileDto.class);

        for (DocFileDto docFileDto : docFileDtoList) {
            //查询创建者用户名
            SysCompanyUserDTO companyUserDTOCreate = userFeign.findUserById(docFileDto.getCreateUserId()).getData();

            docFileDto.setUserName(companyUserDTOCreate.getUserName());
            //查询更新着用户名
            SysCompanyUserDTO companyUserDTOUpdate = userFeign.findUserById(docFileDto.getUpdateUserId()).getData();
            if(companyUserDTOUpdate != null){
                docFileDto.setUpdateUserName(companyUserDTOUpdate.getUserName());
            }
        }

        return docFileDtoList;
    }

    @Autowired
    DocFolderMapper folderMapper ;

    private List<DocFolderDto> queryFolderList(Long parentFolderId) {
        LambdaQueryWrapper<DocFolder> docFolderQw = new LambdaQueryWrapper<>();
        docFolderQw.eq(DocFolder::getParentId, parentFolderId);
        docFolderQw.eq(DocFolder::getCompanyId, CurrentUserHolder.get().getCompanyId());
        docFolderQw.eq(DocFolder::getStatus, 1);
        List<DocFolder> docFolderList = folderMapper.selectList(docFolderQw);
        if(docFolderList != null){
            List<DocFolderDto> docFolderDtos = BeanHelper.copyWithCollection(docFolderList, DocFolderDto.class);
            return docFolderDtos;
        }

        return new ArrayList<>();
    }
}
